package me.zhengjie.stock.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.config.MarketInfoProperties;
import me.zhengjie.stock.domain.TblStockInfo;
import me.zhengjie.stock.pipeline.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Spider;

import java.util.Date;
import java.util.List;

/**
 * 股票爬虫service
 *
 * @author Aaron
 * @date 2020/12/19
 */
@Slf4j
@Service
@AllArgsConstructor
public class StockSpiderService {
    private final StockInfoProcessor stockInfoProcessor;
    private final StockInfoPipeline stockInfoPipeline;
    private final KlineHistoryPipeline klinePipeline;
    private final KlineHistoryProcessor klineProcessor;
    private final KlineTodayPipeline klineTodayPipeline;
    private final TblStockInfoService stockInfoService;
    private final MarketInfoProperties dynamicMarketProperties;

    /**
     * 执行股票信息爬取任务
     * 初始化tbl_stock_info数据时使用
     * 获取市场所有股票信息（小于5500只）pz=10 查询条数
     */
    public void runStockInfoSpider() {
        log.info("------------ start runStockInfoSpider ... --------------");
        dynamicMarketProperties.getMarketInfos().forEach(marketInfo -> {
            Spider.create(stockInfoProcessor).addUrl(marketInfo.getUrl()).addPipeline(stockInfoPipeline).run();
            log.info("----------- runStockInfoSpider finished! for[{}]---------------", marketInfo.getCode());
        });

    }

    /**
     * 执行k线数据爬取任务(今日/最后交易日)
     */
    public void runTradingDateKlineSpider() {
        log.info("------------ start runTradingDateKlineSpider ... --------------");
        try {
            log.info("------------ start runTradingDateKlineSpider ... --------------");
            dynamicMarketProperties.getMarketInfos().forEach(marketInfo -> {
                Spider.create(stockInfoProcessor).addUrl(marketInfo.getKlineUrl()).addPipeline(klineTodayPipeline).run();
                log.info("----------- runTradingDateKlineSpider finished! for[{}]---------------", marketInfo.getCode());
            });
        } catch (Exception e) {
            log.error("runTradingDateKlineSpider error:{}", e);
        }
    }

    /**
     * 执行k线数据爬取任务（历史数据）
     *
     * @param limit     获取条数(开始日期-结束提起交易天数)
     * @param startCode
     * @param endCode
     */
    public void runKlineHistorySpider(Integer limit, String startCode, String endCode) {
        log.info("------------ start runKlineSpider ... --------------");
        LambdaQueryWrapper<TblStockInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TblStockInfo::getOpenStatus, 1);
        queryWrapper.ge(StringUtils.isNotEmpty(startCode), TblStockInfo::getCode, startCode);
        queryWrapper.le(StringUtils.isNotEmpty(endCode), TblStockInfo::getCode, endCode);
        queryWrapper.orderByAsc(TblStockInfo::getCode);
        List<TblStockInfo> stockInfoList = stockInfoService.list(queryWrapper);
        int processed = 0;
        String[] urls = stockInfoList.stream().map(stockInfo -> jointKlineUrl(stockInfo.getCode(), stockInfo.getMarket(), limit)).toArray(String[]::new);
        processed += 1;
        log.info("----------- runKlineSpider finished! ---------------");
        Spider.create(klineProcessor).addPipeline(klinePipeline).addUrl(urls).run();
        log.info("----------- runKlineSpider finished! processed:{} ---------------", processed);
    }

    /**
     * 拼接股票k线数据url
     *
     * @param code   股票编码
     * @param market 市场，0 深证，1 上证
     * @param limit  获取记录数，默认250
     */
    private String jointKlineUrl(String code, Integer market, Integer limit) {
        String secid = market + "." + code;
        long time = new Date().getTime();
        if (limit == null) limit = 250;
        String url = "http://push2his.eastmoney.com/api/qt/stock/kline/get" + "?cb=jQuery112405483852141023604_1608302055953" + "&secid=" + secid + "&ut=fa5fd1943c7b386f172d6893dbfba10b" + "&fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61" + "&klt=101&fqt=0" + "&end=20500101" + "&lmt=" + limit + "&_=" + time;
        return url;
    }


}
